package org.jwos.plugin.file.util;

import java.io.IOException;
import java.io.InputStream;

public class ObservedInputStream extends InputStream {
	
	private InputStream targetStream;
	
	private long readedCount = 0;
	
	private long skipedCount = 0;
	
	private long markedCount = 0;
	
	private long startTime = -2;
	
	private long completeTime = -1;
	
	public ObservedInputStream() {
	}
	
	public ObservedInputStream(InputStream targetStream) {
		this.targetStream = targetStream;
	}

	public int read() throws IOException {
		
		if(startTime<=0) {
			startTime = System.currentTimeMillis();
		}
		
		int data = targetStream.read();
		
		if(data!=-1) {
			readedCount++;
		} else {
			if(completeTime<=0) {
				completeTime = System.currentTimeMillis();
			}
		}
		
		return data;
	}
	
	public int read(byte b[]) throws IOException {
		
		if(startTime<=0) {
			startTime = System.currentTimeMillis();
		}
		
		int readed = targetStream.read(b);
		
		if(readed!=-1) {
			readedCount += readed;
		} else {
			if(completeTime<=0) {
				completeTime = System.currentTimeMillis();
			}
		}
		
		return readed;
	}
	
	public int read(byte b[], int off, int len) throws IOException {
		
		if(startTime<=0) {
			startTime = System.currentTimeMillis();
		}
		
		int readed = targetStream.read(b, off, len);
		
		if(readed!=-1) {
			readedCount += readed;
		} else {
			if(completeTime<=0) {
				completeTime = System.currentTimeMillis();
			}
		}
		
		return readed;
	}
	
	public long skip(long n) throws IOException {
		
		if(startTime<=0) {
			startTime = System.currentTimeMillis();
		}
		
		long skiped = targetStream.skip(n);
		
		skipedCount += skiped;
		
		return skiped;
	}
	
	public int available() throws IOException {
		return targetStream.available();
	}
	
	public void close() throws IOException {
		targetStream.close();
	}
	
	public synchronized void mark(int readlimit) {
		targetStream.mark(readlimit);
		markedCount = readedCount;
	}
	
	public synchronized void reset() throws IOException {
		targetStream.reset();
		readedCount = markedCount;
	}
	
	public boolean markSupported() {
		return targetStream.markSupported();
	}

	public InputStream getTargetStream() {
		return targetStream;
	}

	public void setTargetStream(InputStream targetStream) {
		this.targetStream = targetStream;
	}

	public long getReadedCount() {
		return readedCount;
	}

	public long getTotalCount() {
		return readedCount + skipedCount;
	}

	public long getStartTime() {
		return startTime;
	}

	public long getCompleteTime() {
		return completeTime;
	}

}
